/*
 * DemoModule.java  0.4.0 / Oct 24, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
package com.cute4j.demos.swingset;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ResourceBundle;

import com.cute4j.swing.Component;
import com.cute4j.swing.Icon;
import com.cute4j.swing.ImageIcon;
import com.cute4j.swing.Swing;
import com.cute4j.util.Utilities;

/**
 * Abstract Demo Module.
 *
 * @author Slobodan Vrkacevic
 * @version 0.4.0
 */
public abstract class DemoModule {

// Private Fields. -------------------------------------------------------------

  private final String name;
  private final String description;
  private final Icon icon;
  private Component component; // NOPMD
  private String sourceCode; // NOPMD

// Protected Constructors. -----------------------------------------------------

  /**
   * Constructs new DemoModule object.
   *
   * @param name the demo name
   * @param description the demo description
   */
  protected DemoModule(String name, String description) {
    this.name = name;
    this.description = description;
    String demoIconName = "resources/images/" + getClassName() + ".png";
    icon = new ImageIcon(loadResource(demoIconName)); // NOPMD
  }

  /**
   * Constructs new DemoModule object.
   *
   * @param name the demo name
   * @param description the demo description
   * @param icon the demo icon
   */
  protected DemoModule(String name, String description, Icon icon) {
    this.name = name;
    this.description = description;
    this.icon = icon;
  }

// Public Methods. -------------------------------------------------------------

  /**
   * Returns demo name.
   *
   * @return demo name
   */
  public String getName() {
    return name;
  }

  /**
   * Returns demo description.
   *
   * @return demo description
   */
  public String getDescription() {
    return description;
  }

  /**
   * Returns demo icon.
   *
   * @return demo icon
   */
  public Icon getIcon() {
    return icon;
  }

  /**
   * Returns demo component.
   *
   * @return demo component
   */
  public Component getComponent() {
    if (component == null) {
      component = buildDemoComponent();
    }
    return component;
  }

  /**
   * Returns demo source code.
   *
   * @return demo source code
   */
  public String getSourceCode() {
    if (sourceCode == null) {
      sourceCode = loadSourceCode();
    }
    return sourceCode;
  }

// Protected Methods. ----------------------------------------------------------

  /**
   * Builds demo component.
   *
   * @return demo component
   */
  protected abstract Component buildDemoComponent();

  /**
   * Loads demo source code.
   *
   * @return demo source code
   */
  protected String loadSourceCode() {
    try {
      String demoName = getClassName() + ".java";
      return Utilities.toString(loadResourceAsStream(demoName));
    } catch (IOException ex) {
      return "Could not load source code";
    }
  }

  /**
   * Loads the specified resource.
   *
   * @param resourceName the resource name
   *
   * @return the resource url
   */
  protected URL loadResource(String resourceName) {
    return getClass().getResource(resourceName);
  }

  /**
   * Loads the specified resource.
   *
   * @param resourceName the resource name
   *
   * @return the resource url
   */
  protected InputStream loadResourceAsStream(String resourceName) {
    return getClass().getResourceAsStream(resourceName);
  }

  /**
   * Returns text from the main resource bundle.
   *
   * @param text String
   * @return String
   */
  protected String getText(String text) {
    ResourceBundle bundle = ResourceBundle.getBundle(
                                "com/cute4j/demos/swingset/resources/Text");
    return bundle.getString(text);
  }

  /**
   * Returns the name of the demo class.
   *
   * @return the name of the demo class
   */
  protected String getClassName() {
    Class demoClass = getClass();
    String className = demoClass.getName();
    return className.substring(className.lastIndexOf('.') + 1);
  }

  /**
   * Displays demo as standalone window.
   */
  protected void show() {
    Component component = getComponent();
    component.setName(getName());
    component.setVisible(true);
    Swing.startEventLoop();
  }

}
